﻿using IOA.MES.Client.Common;
using IOA.MES.Client.Models.Response;
using IOA.MES.Common;
using NLog;
using Seagull.BarTender.Print;
using System;
using System.Collections.Generic;
using System.Data.OleDb;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Input;

namespace IOA.MES.Client.Laminator
{
    /// <summary>
    /// WinRePrint.xaml 的交互逻辑
    /// </summary>
    public partial class WinLaminatorRePrint : System.Windows.Window
    {
        private int downloadStatus = 0;
        private Models.Response.Label label = null;
        private string printer = BaseEnv.GetStorage("叠层条码");
        private int printCount = Convert.ToInt32(BaseEnv.GetStorage("叠层条码数量") ?? "0");

        public WinLaminatorRePrint()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            InitWorkOrders();
        }

        public void InitWorkOrders()
        {
            var workOrderNos = BaseEnv.InvokeApi<List<string>>("/api/WorkOrder/QueryWorkshopWorkOrders", new { }).Data;
            workOrderNos.Insert(0, "请选择");
            cbWorkOrder.ItemsSource = workOrderNos;
            cbWorkOrder.SelectedIndex = 0;
        }

        private void txtBarCode_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                btnPrint_Click(null, null);
            }
        }

        private void btnPrint_Click(object sender, RoutedEventArgs e)
        {
            var userName = txtUserName.Text.Trim();
            var password = txtPassword.Password.Trim();
            var workOrderNo = Convert.ToString(cbWorkOrder.SelectedValue).Replace("请选择", "");
            var barCode = txtBarCode.Text.Trim();

            if (string.IsNullOrWhiteSpace(printer))
            {
                CommonMessage.Alert(this, "请设置打印机");
                return;
            }
            else if (string.IsNullOrWhiteSpace(userName))
            {
                CommonMessage.Alert(this, "请填写补打账号");
                return;
            }
            else if (string.IsNullOrWhiteSpace(password))
            {
                CommonMessage.Alert(this, "请填写补打密码");
                return;
            }
            else if (string.IsNullOrWhiteSpace(workOrderNo))
            {
                CommonMessage.Alert(this, "请选择补打工单");
                return;
            }
            else if (string.IsNullOrWhiteSpace(barCode))
            {
                CommonMessage.Alert(this, "请输入补打条码");
                return;
            }

            RePrint(userName, password, workOrderNo, barCode);
            txtBarCode.Text = "";
            txtBarCode.Focus();
        }

        private void RePrint(string userName, string password, string workOrderNo, string barCode)
        {
            var getWorkOrderLabelsResponse = BaseEnv.InvokeApi<GetWorkOrderLabelsResponse>("/api/Machine/GetWorkOrderLabelsPreview", new
            {
                WorkOrderNo = workOrderNo
            });
            if (getWorkOrderLabelsResponse.ErrCode != 200)
            {
                CommonMessage.Alert(this, getWorkOrderLabelsResponse.ErrMsg);
                return;
            }
            label = getWorkOrderLabelsResponse.Data.Labels.FirstOrDefault(_ => string.Equals(_.LabelName, "序列号", StringComparison.CurrentCultureIgnoreCase));
            if (label == null)
            {
                CommonMessage.Alert(this, "请上传工单序列号模板");
                return;
            }
            else if (!DownloadLabels(label))
            {
                return;
            }

            var getNewBarCodeResponse = BaseEnv.InvokeApi<object>("/api/WorkOrder/CheckRePrintBarCode", new
            {
                UserName = userName,
                Password = password,
                WorkOrderNo = workOrderNo,
                BarCode = barCode
            });
            if (getNewBarCodeResponse.ErrCode != 200)
            {
                CommonMessage.Alert(this, getNewBarCodeResponse.ErrMsg);
                return;
            }

            if (printCount > 0)
            {
                label.LabelData = new List<KeyValuePair<string, string>>
                {
                    new KeyValuePair<string, string>("条码", barCode)
                };
                PrintLabels(label);
            }
        }

        /// <summary>
        /// 打印条码
        /// </summary>
        private void PrintLabels(Models.Response.Label labels)
        {
            var engine = new Engine(true);
            try
            {
                var btw = $"{BaseEnv.LocalDirectory}\\data\\{label.LabelFile.Substring(label.LabelFile.LastIndexOf("/") + 1)}";
                var keys = label.LabelData.Select(_ => _.Key).ToList();
                var values = label.LabelData.Select(_ => $"'{_.Value}'").ToList();
                var sql = $"({string.Join(", ", keys)}) VALUES ({string.Join(", ", values)})";
                ExcuteSql($"DELETE FROM {label.TableName}");
                ExcuteSql($"INSERT INTO {label.TableName} {sql}");

                var format = !engine.Documents.Any(_ => string.Equals(_.FileName, btw, StringComparison.CurrentCultureIgnoreCase)) ? engine.Documents.Open(btw) :
                    engine.Documents.FirstOrDefault(_ => string.Equals(_.FileName, btw, StringComparison.CurrentCultureIgnoreCase));
                try
                {
                    if (format.PrintSetup.SupportsIdenticalCopies)
                    {
                        format.PrintSetup.IdenticalCopiesOfLabel = printCount;
                    }

                    format.PrintSetup.PrinterName = printer;
                    int waitForCompletionTimeout = 10000;//10秒
                    Messages messages;
                    var result = format.Print($"PrintCodes_{DateTime.Now.ToLongDateString()}", waitForCompletionTimeout, out messages);
                    var msgs = new List<string>();
                    foreach (var msg in messages)
                    {
                        msgs.Add(msg.Text);
                    }
                    CommonMessage.Log(LogLevel.Info, string.Join("\r\n", msgs));
                }
                catch (Exception ex)
                {
                    CommonMessage.Alert(this, $"标签打印出错，请重新尝试：{ex.Message}");
                    CommonMessage.Log(LogLevel.Fatal, $"标签打印出错：{ex.Message}", ex);
                }
                finally
                {
                    try
                    {
                        format.Close(SaveOptions.DoNotSaveChanges);
                    }
                    catch (Exception ex)
                    {
                        CommonMessage.Log(LogLevel.Fatal, $"format.Close异常：{ex.Message}", ex);
                    }
                }
            }
            catch (Exception ex)
            {
                CommonMessage.Alert(this, $"标签打印异常：{ex.ToString()}");
            }
            finally
            {
                engine.Dispose();
            }
        }

        /// <summary>
        /// 下载标签
        /// </summary>
        private bool DownloadLabels(Models.Response.Label labels)
        {
            downloadStatus = 0;

            var btwFolder = $@"{BaseEnv.LocalDirectory}\data";
            if (!Directory.Exists(btwFolder))
            {
                Directory.CreateDirectory(btwFolder);
            }
            try
            {
                var fileName = labels.LabelFile.Substring(labels.LabelFile.LastIndexOf("/") + 1);
                var filePath = $@"{btwFolder}\{fileName}";
                if (!File.Exists(filePath))
                {
                    new FtpUtils(BaseEnv.UserInfo.FtpConfig.UserName, BaseEnv.UserInfo.FtpConfig.Password).Download(labels.LabelFile, filePath);
                }
            }
            catch (Exception ex)
            {
                CommonMessage.Alert(this, $"标签文件下载失败\r\nLabel file download failed：\r\n{labels.LabelName}");
                downloadStatus = 2;
                return false;
            }
            downloadStatus = 1;
            return true;
        }

        /// <summary>
        /// 执行SQL
        /// </summary>
        private void ExcuteSql(string sql)
        {
            string strConn = $@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={BaseEnv.LocalDirectory}\\data\\data.mdb";
            var myConn = new OleDbConnection(strConn);
            try
            {
                myConn.Open();
                var inst = new OleDbCommand(sql, myConn);
                inst.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                CommonMessage.Alert(this, $"执行SQL异常，请重新尝试：{ex.Message}");
                CommonMessage.Log(LogLevel.Fatal, $"执行SQL异常：{ex.Message}", ex);
            }
            if (myConn.State != System.Data.ConnectionState.Closed)
            {
                myConn.Close();
            }
        }
    }
}
